package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.util.NumberUtil;
import com.tbit.uqbike.object.pojo.AccountUser;
import com.tbit.uqbike.object.pojo.BleBeacon;
import com.tbit.uqbike.object.pojo.ParkPointBound;
import com.tbit.uqbike.object.pojo.ParkPointBoundAbnormal;
import com.tbit.uqbike.service.business.EquipmentMaintainService;
import com.tbit.uqbike.webmanager.dao.core.AccountUserDao;
import com.tbit.uqbike.webmanager.dao.core.BleBeaconDao;
import com.tbit.uqbike.webmanager.dao.core.EquipmentMaintainDao;
import com.tbit.uqbike.webmanager.util.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author HZW
 * @ClassName EquipmentMaintainServiceImpl
 * @Description 设备维修业务层
 * @date 2021/12/16 9:54
 * @Version 1.0
 */
@Service("equipmentMaintainService")
public class EquipmentMaintainServiceImpl implements EquipmentMaintainService {
    @Resource
    private EquipmentMaintainDao equipmentMaintainDao;
    @Resource
    private BleBeaconDao bleBeaconDao;
    @Resource
    private AccountUserDao accountUserDao;

    @Override
    public Map<String, Object> selectAbnormalTotal(ParkPointBoundAbnormal parkPointBoundAbnormal) {
        Map<String, Object> map = new HashMap<>(3);
        /**道钉数据*/
        List<Map<String, Object>> spikeData = new ArrayList<>();
        /**rfid数据*/
        List<Map<String, Object>> rfidData = new ArrayList<>();
        /**获取区域内站点设备异常数据*/
        List<ParkPointBoundAbnormal> list = equipmentMaintainDao.selectAbnormalTotal(parkPointBoundAbnormal);
        if (!list.isEmpty()) {
            for (ParkPointBoundAbnormal pointBoundAbnormal : list) {
                Map<String, Object> spikeMap = new HashMap<>(6);
                Map<String, Object> rfidMap = new HashMap<>(6);
                if (pointBoundAbnormal.getType().equals(0) && pointBoundAbnormal.getState().equals(1)) {
                    spikeMap.put("name", "道钉运维标记故障数");
                    spikeMap.put("value", pointBoundAbnormal.getSum());
                } else if (pointBoundAbnormal.getType().equals(0) && pointBoundAbnormal.getState().equals(2)) {
                    spikeMap.put("name", "道钉系统标记故障数");
                    spikeMap.put("value", pointBoundAbnormal.getSum());
                } else if (pointBoundAbnormal.getType().equals(1) && pointBoundAbnormal.getState().equals(1)) {
                    rfidMap.put("name", "RFID运维标记故障数");
                    rfidMap.put("value", pointBoundAbnormal.getSum());
                } else if (pointBoundAbnormal.getType().equals(1) && pointBoundAbnormal.getState().equals(2)) {
                    rfidMap.put("name", "RFID系统标记故障数");
                    rfidMap.put("value", pointBoundAbnormal.getSum());
                }
                if (!spikeMap.isEmpty()) {
                    spikeData.add(spikeMap);
                }
                if (!rfidMap.isEmpty()) {
                    rfidData.add(rfidMap);
                }
            }
        }
        /**获取区域内所有的rfid数量*/
        Integer RFIDTotal = equipmentMaintainDao.getRFIDTotal(new ParkPointBound(parkPointBoundAbnormal.getAddTime(), parkPointBoundAbnormal.getAccountId()));
        /**获取异常的rfid数量*/
        Integer RFIDAbnormalTotal = 0;
        List<Collection<Object>> valueList = new ArrayList<>();
        for (Map<String, Object> rfidDatum : rfidData) {
            if (!rfidDatum.isEmpty()) {
                RFIDAbnormalTotal += Integer.parseInt(rfidDatum.get("value").toString());
                valueList.add(rfidDatum.values());
            }
        }
        /**判断是否存在rfid运维标记故障数，不存在补0*/
        Boolean flag = valueList.stream().filter(value -> value.contains("RFID运维标记故障数")).findAny().isPresent();
        /**判断是否存在rfid系统标记故障数，不存在补0*/
        Boolean flagSystem = valueList.stream().filter(value -> value.contains("RFID系统标记故障数")).findAny().isPresent();
        valueList.clear();
        if (!flag) {
            Map<String, Object> valueMap = new HashMap<>(3);
            valueMap.put("name", "RFID运维标记故障数");
            valueMap.put("value", 0);
            rfidData.add(valueMap);
        }
        if (!flagSystem) {
            Map<String, Object> valueMap = new HashMap<>(3);
            valueMap.put("name", "RFID系统标记故障数");
            valueMap.put("value", 0);
            rfidData.add(valueMap);
        }

        /**获取正常的rfid数量*/
        Map<String, Object> normalRFIDTotal = new HashMap<>(3);
        normalRFIDTotal.put("name", "RFID正常数量");
        normalRFIDTotal.put("value", RFIDTotal - RFIDAbnormalTotal);
        rfidData.add(normalRFIDTotal);


        /**获取区域内所有的道钉数量*/
        Integer spikeTotal = bleBeaconDao.getSpikeTotal(new BleBeacon(new Date(), parkPointBoundAbnormal.getAccountId()));
        /**获取异常的道钉数量*/
        Integer spikeAbnormalTotal = 0;
        for (Map<String, Object> spikeDatum : spikeData) {
            if (!spikeDatum.isEmpty()) {
                spikeAbnormalTotal += Integer.parseInt(spikeDatum.get("value").toString());
                valueList.add(spikeDatum.values());
            }
        }
        /**判断是否存在道钉运维标记故障数，不存在补0*/
        Boolean flagSpike = valueList.stream().filter(value -> value.contains("道钉运维标记故障数")).findAny().isPresent();
        /**判断是否存在道钉系统标记故障数，不存在补0*/
        Boolean flagSpikeSystem = valueList.stream().filter(value -> value.contains("道钉系统标记故障数")).findAny().isPresent();
        valueList.clear();
        if (!flagSpike) {
            Map<String, Object> valueMap = new HashMap<>(3);
            valueMap.put("name", "道钉运维标记故障数");
            valueMap.put("value", 0);
            spikeData.add(valueMap);
        }
        if (!flagSpikeSystem) {
            Map<String, Object> valueMap = new HashMap<>(3);
            valueMap.put("name", "道钉系统标记故障数");
            valueMap.put("value", 0);
            spikeData.add(valueMap);
        }
        /**获取正常的道钉数量 */
        Map<String, Object> normalSpikeTotal = new HashMap<>(3);
        normalSpikeTotal.put("name", "道钉正常数量");
        normalSpikeTotal.put("value", spikeTotal - spikeAbnormalTotal);
        spikeData.add(normalSpikeTotal);

        map.put("rfid", rfidData);
        map.put("spike", spikeData);

        return map;
    }

    @Override
    public List<ParkPointBound> getInfo(ParkPointBound parkPointBound) {
        /**获取区域内所有的运维人员*/
        List<AccountUser> accountUserList = accountUserDao.getByType(parkPointBound.getAccountId(), false);
        Map<Integer, Object> accountUserMap = new HashMap<>(2);
        if (!accountUserList.isEmpty()) {
            for (AccountUser accountUser : accountUserList) {
                accountUserMap.put(accountUser.getAccountUserId(), accountUser);
            }
        }
        List<ParkPointBound> bleList = new ArrayList<>();
        if (null == parkPointBound.getType() || 0 == parkPointBound.getType()) {
            /**获取区域下所有的道钉设备*/
            bleList = bleBeaconDao.getBlebeaconByaccountId(parkPointBound);
            if (!bleList.isEmpty()) {
                for (ParkPointBound pointBound : bleList) {
                    if (null != pointBound.getUserMainId()) {
                        /**将异常举报人的名称拼接*/
                        AccountUser accountUser = (AccountUser) accountUserMap.get(pointBound.getUserMainId());
                        if (null != accountUser && StringUtils.isNotEmpty(accountUser.getName())) {
                            pointBound.setUserMainName(accountUser.getName());
                        }
                    }
                }
            }
        }
        /**获取rfid的数据和道钉及rfid的异常数据*/
        List<ParkPointBound> list = equipmentMaintainDao.getRFIDInfo(parkPointBound);
        if (!list.isEmpty()) {
            for (ParkPointBound pointBound : list) {
                if (null != pointBound.getUserMainId()) {
                    /**将异常举报人的名称拼接*/
                    AccountUser accountUser = (AccountUser) accountUserMap.get(pointBound.getUserMainId());
                    if (null != accountUser && StringUtils.isNotEmpty(accountUser.getName())) {
                        pointBound.setUserMainName(accountUser.getName());
                    }
                }
            }
        }
        if (!bleList.isEmpty()) {
            /**将查询出的道钉一起返回去*/
            for (ParkPointBound bound : bleList) {
                list.add(bound);
            }
        }
        if (null != parkPointBound.getState()) {
            if (0 == parkPointBound.getState()) {
                list.removeIf(data -> null != data.getAddTime());
            } else if (1 == parkPointBound.getState()) {
                list.removeIf(data -> 1 != data.getState());
            } else if (2 == parkPointBound.getState()) {
                list.removeIf(data -> 2 != data.getState());
            }
        }
        return list;
    }


    @Override
    public List<ParkPointBoundAbnormal> getAbnormalInfo(ParkPointBoundAbnormal parkPointBoundAbnormal) {
        List<ParkPointBoundAbnormal> list = new ArrayList<>();
        List<ParkPointBoundAbnormal> dataList = new LinkedList<>();
        if (parkPointBoundAbnormal.getType() == 0) {
            dataList = equipmentMaintainDao.getSpikeData(parkPointBoundAbnormal.getAccountId(), parkPointBoundAbnormal.getParkPointName());
            Map<Integer, ParkPointBoundAbnormal> collect = dataList.stream().collect(Collectors.toMap(ParkPointBoundAbnormal::getParkPointId, x -> {
                if (x.getState() == 0) {
                    x.setNormalTotal(x.getSum());
                } else if (x.getState() == 1) {
                    x.setOperationsAbnormalTotal(x.getSum());
                } else {
                    x.setSystemAbnormalTotal(x.getSum());
                }
                return x;

            }, (x, y) -> {
                if (y.getState() == 0) {
                    x.setNormalTotal(y.getSum());
                } else if (y.getState() == 1) {
                    x.setOperationsAbnormalTotal(y.getSum());
                } else {
                    x.setSystemAbnormalTotal(y.getSum());
                }
                return x;
            }));
            list.addAll(collect.values().stream().collect(Collectors.toList()));
        } else if (parkPointBoundAbnormal.getType() == 1) {
            dataList = equipmentMaintainDao.getData(parkPointBoundAbnormal);
            Map<Integer, ParkPointBoundAbnormal> collect = dataList.stream().collect(Collectors.toMap(ParkPointBoundAbnormal::getParkPointId, x -> {
                if (x.getState() == 0) {
                    x.setNormalTotal(x.getSum());
                } else if (x.getState() == 1) {
                    x.setOperationsAbnormalTotal(x.getSum());
                } else {
                    x.setSystemAbnormalTotal(x.getSum());
                }
                return x;

            }, (x, y) -> {
                if (y.getState() == 0) {
                    x.setNormalTotal(y.getSum());
                } else if (y.getState() == 1) {
                    x.setOperationsAbnormalTotal(y.getSum());
                } else {
                    x.setSystemAbnormalTotal(y.getSum());
                }
                return x;
            }));
            list.addAll(collect.values().stream().collect(Collectors.toList()));
        }
        return list;
    }

    @Override
    public List<ParkPointBoundAbnormal> dataFormat(List<ParkPointBoundAbnormal> abnormalInfo) {
        for (ParkPointBoundAbnormal p : abnormalInfo) {
            p.setNewSum((int)NumberUtil.add(p.getSystemAbnormalTotal(), p.getOperationsAbnormalTotal()));
            p.setNewNormalTotal(NumberUtil.add(p.getSystemAbnormalTotal(), p.getOperationsAbnormalTotal(), p.getNormalTotal()).intValue());
        }
        return abnormalInfo;
    }
}
